
// 中介者模式：
// 定义一个对象来封装一系列对象的交互。中介者模式使各个对象之间不需要显示地相互引用，
// 从而使其耦合松散，而且用户可以独立地改变它们之间的交互。
 
// 公共头文件
#include <iostream>
#include <string>
#include <vector>
using namespace std;
 
enum PERSON_TYPE
{
	NONE_PERSON,
	LANDLORD,
	TENANT
};
 
// 公共头文件 end

class Mediator;
class Colleague;

// 抽象中介者
class Mediator
{
public:
	Mediator(){}
	// 声明抽象方法
	virtual void operation(Colleague*) = 0;
	// 声明注册方法
	virtual void registerMethod(Colleague*) = 0;
};

// 抽象同事类
class Colleague
{
public:
	Colleague(){}
	void setMediator(Mediator* iMediator){
		this->mediator = iMediator;
	}
	Mediator* getMediator(){
		return this->mediator;
	}
	void setPersonType(PERSON_TYPE iPersonType){
		this->personType = iPersonType;
	}
	PERSON_TYPE getPersonType(){
		return this->personType;
	}
	virtual void ask() = 0;
	virtual void answer() = 0;
private:
	PERSON_TYPE personType;
	Mediator* mediator;
};

// 具体同事类：租客
class Tenant :public Colleague
{
public:
	Tenant();
	Tenant(string name);
	void ask();
	void answer();
private:
	string name;
};
 
Tenant::Tenant(){
	name = "none";
	setPersonType(NONE_PERSON);
}
 
Tenant::Tenant(string iName){
	name = iName;
	setPersonType(TENANT);
}
 
void Tenant::ask(){
	printf("租客%s询问房东信息\n", name.c_str()); 
	(this->getMediator())->operation(this);
}
 
void Tenant::answer(){
	printf("租客姓名：%s\n", name.c_str());
}



// 具体同事类：房东
class Landlord :public Colleague
{
public:
	Landlord();
	Landlord(string iName, int iPrice, string iAddress, string iPhoneNum);
	void ask();
	void answer();
private:
	string name;
	int price;
	string address;
	string phoneNumber;
};

 
Landlord::Landlord(){
	name = "none";
	price = 0;
	address = "none";
	phoneNumber = "none";
	setPersonType(NONE_PERSON);
}
 
Landlord::Landlord(string iName, int iPrice, 
	string iAddress, string iPhoneNum){
	name = iName;
	price = iPrice;
	address = iAddress;
	phoneNumber = iPhoneNum;
	setPersonType(LANDLORD);
}
 
void Landlord::answer(){
	printf("房东姓名：%s, 房租：%d, 地址：%s, 联系电话：%s\n",
		name.c_str(), price, address.c_str(), phoneNumber.c_str());
}
 
void Landlord::ask(){
	printf("房东%s查看租客信息：\n",name.c_str());
	(this->getMediator())->operation(this);
}



// 具体中介者
class Agency:public Mediator
{
public:
	Agency(){}
	void registerMethod(Colleague* person){
		switch (person->getPersonType()){
		case LANDLORD:
			landlordList.push_back((Landlord*)person);
			break;
		case TENANT:
			tenantList.push_back((Tenant*)person);
			break;
		default:
			printf("wrong person\n");
		}
	}
	void operation(Colleague* person){
		switch (person->getPersonType()){
		case LANDLORD:
			for (int i = 0; i < tenantList.size(); i++){
				tenantList[i]->answer();
			}
			break;
		case TENANT:
			for (int i = 0; i < landlordList.size(); i++){
				landlordList[i]->answer();
			}
			break;
		default:
			break;
		}
	}
private:
	vector<Landlord*>landlordList;
	vector<Tenant*>tenantList;
};
 
int main()
{
	// 创建租房中介
	Agency *mediator = new Agency();
 
	// 创建3位房东
	Landlord *fangdong1 = new Landlord("刘备", 1350, "成都市双流区", "1351025");
	Landlord *fangdong2 = new Landlord("关羽", 1500, "成都市武侯区", "1378390");
	Landlord *fangdong3 = new Landlord("张飞", 1000, "成都市龙泉驿", "1881166");
	fangdong1->setMediator(mediator);
	fangdong2->setMediator(mediator);
	fangdong3->setMediator(mediator);
	// 房东在中介处登记注册房源信息
	mediator->registerMethod(fangdong1);
	mediator->registerMethod(fangdong2);
	mediator->registerMethod(fangdong3);
 
	// 创建两位租客Jungle和贱萌兔
	Tenant *jungle = new Tenant("Jungle");
	Tenant *jianmengtu = new Tenant("贱萌兔");
	jungle->setMediator(mediator);
	jianmengtu->setMediator(mediator);
	// Jungle和贱萌兔在中介处登记求租信息
	mediator->registerMethod(jungle);
	mediator->registerMethod(jianmengtu);
 
	jungle->ask();
	printf("\n\n");
	fangdong1->ask();
 
	printf("\n\n");
	system("pause");
	return 0;
}